// 展示acm风格的测试方式
// 子矩阵的最大累加和问题，不要求会解题思路，后面的课会讲
// 每一组测试都给定数据规模
// 任何空间都提前生成好，一律都是静态空间，然后自己去复用，推荐这种方式
// 测试链接 : https://www.nowcoder.com/practice/cb82a97dcd0d48a7b1f4ee917e2c0409?
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code，可以直接通过

#include <bits/stdc++.h>

using namespace std;

// 题目给定的行的最大数据量
const int MAXN = 201;
// 题目给定的列的最大数据量
const int MAXM = 201;
// 申请这么大的矩阵空间，一定够用了
// 静态的空间，不停复用
int mat[MAXN][MAXN];
// 需要的所有辅助空间也提前生成
// 静态的空间，不停复用
int arr[MAXN];
// 当前测试数据行的数量是n
// 当前测试数据列的数量是m
// 这两个变量可以把代码运行的边界规定下来
int n, m;

inline int read()
{
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = 10 * x + ch - '0';
        ch = getchar();
    }
    return f * x;
}

// 求子数组的最大累加和，后面的课会讲
int maxSumSubarray()
{
    int mx = INT_MIN;
    int cur = 0;
    for(int i = 0; i < m; ++i)
    {
        cur += arr[i];
        mx = max(mx, cur);
        cur = cur < 0 ? 0 : cur;
    }
    return mx;
}

// 求子矩阵的最大累加和，后面的课会讲
int maxSumSubmatrix()
{
    int mx = INT_MIN;
    // 将矩阵压缩成数组
    for(int i = 0; i < n; ++i)
    {
        // i ~ j 行的矩阵压缩成 arr 数组
        // 因为之前的过程可能用过辅助数组
        // 为了让之前结果不干扰到这次运行，需要自己清空辅助数组需要用到的部分
        memset(arr, 0, sizeof arr);
        for(int j = i; j < n; ++j)
        {
            for(int k = 0; k < m; ++k)
            {
                arr[k] += mat[j][k];
            }
            mx = max(mx, maxSumSubarray());
        }
    }
    return mx;
}

int main()
{
    n = read(), m = read();
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            mat[i][j] = read();
        }
    }
    printf("%d\n", maxSumSubmatrix());

    return 0;
}